package com.crm.config.filter;

import cn.hutool.json.JSONUtil;
import com.crm.commons.domain.ResponseData;
import com.crm.util.JwtTokenUtil;
import com.crm.entity.CrmUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.stream.Collectors;


@Slf4j
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    String[] whiteList = {"/crm/user/login"};


    @Override
    protected void doFilterInternal(HttpServletRequest request, javax.servlet.http.HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        log.info("过滤器JwtAuthenticationFilter"+request.getRequestURI());

        for (String s : whiteList) {
            if (s.equals(request.getRequestURI())) {
                doFilter(request, response, filterChain);
                return;
            }
        }
        String strAuth = request.getHeader("Authorization");
        if (StringUtils.isEmpty(strAuth)) {
            doFilter(request, response, filterChain);
            return;
        }
        String jwtToken = strAuth.replace("Bearer ", "");
        if (StringUtils.containsWhitespace(jwtToken)) {
            ResponseData responseData = new ResponseData(-1, "请重新登录");
            printToken(request, response, responseData);
            return;
        }
        //校验jwt
        boolean verifyResult = JwtTokenUtil.verifyToken(jwtToken);
        if (!verifyResult) {
            ResponseData responseData = new ResponseData(-1, "请重新登录");
            printToken(request, response, responseData);
            return;
        }

        //从jwt里获取用户信息和权限信息
        String userInfo = JwtTokenUtil.getUserInfoFromToken(jwtToken);
        List<String> userAuthList = JwtTokenUtil.getUserAuthFromToken(jwtToken);
        //反序列化成SysUser对象
        CrmUser sysUser = JSONUtil.parseObj(userInfo).toBean(CrmUser.class);
        List<SimpleGrantedAuthority> authorityList = userAuthList.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList());
        //用户名密码认证token
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(sysUser, null, authorityList);
        //把token放到安全上下文：securityContext
        SecurityContextHolder.getContext().setAuthentication(token);
        doFilter(request, response, filterChain); //放行
    }

    private void printToken(HttpServletRequest request, HttpServletResponse response, ResponseData responseData) throws IOException {
        String strResponse = JSONUtil.toJsonStr(responseData);
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println(strResponse);
        writer.flush();
    }
}
